package com.ken.apollo.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ken.apollo.domain.entity.MailSenderConfig;
import com.ken.apollo.mapper.MailSenderConfigMapper;
import com.ken.apollo.service.MailSenderConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Properties;

/**
 * 邮件发送方配置Service实现类
 *
 * @author Ken
 * @since 2025-08-25
 */
@Slf4j
@Service
public class MailSenderConfigServiceImpl extends ServiceImpl<MailSenderConfigMapper, MailSenderConfig> 
        implements MailSenderConfigService {
    
    @Override
    public MailSenderConfig getDefaultConfig() {
        return this.lambdaQuery()
                .eq(MailSenderConfig::getIsDefault, true)
                .eq(MailSenderConfig::getStatus, true)
                .one();
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setDefaultConfig(Long id) {
        // 先取消所有默认配置
        this.lambdaUpdate()
                .set(MailSenderConfig::getIsDefault, false)
                .update();
        
        // 设置新的默认配置
        return this.lambdaUpdate()
                .eq(MailSenderConfig::getId, id)
                .set(MailSenderConfig::getIsDefault, true)
                .update();
    }
    
    @Override
    public List<MailSenderConfig> listByCondition(String configName, String senderEmail, Boolean status) {
        LambdaQueryWrapper<MailSenderConfig> wrapper = new LambdaQueryWrapper<>();
        
        if (StrUtil.isNotBlank(configName)) {
            wrapper.like(MailSenderConfig::getConfigName, configName);
        }
        
        if (StrUtil.isNotBlank(senderEmail)) {
            wrapper.like(MailSenderConfig::getSenderEmail, senderEmail);
        }
        
        if (ObjectUtil.isNotNull(status)) {
            wrapper.eq(MailSenderConfig::getStatus, status);
        }
        
        return this.list(wrapper.orderByDesc(MailSenderConfig::getCreateTime));
    }
    
    @Override
    public boolean testConfig(Long configId, String testEmail) {
        MailSenderConfig config = this.getById(configId);
        if (config == null) {
            throw new RuntimeException("配置不存在");
        }
        
        try {
            JavaMailSender mailSender = createMailSender(config);
            
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom(config.getSenderEmail());
            message.setTo(testEmail);
            message.setSubject("邮件配置测试");
            message.setText("这是一封测试邮件，用于验证邮件发送配置是否正确。\\n\\n配置名称：" + config.getConfigName() + 
                          "\\n发送时间：" + java.time.LocalDateTime.now());
            
            mailSender.send(message);
            
            log.info("邮件配置测试成功，配置ID：{}，测试邮箱：{}", configId, testEmail);
            return true;
        } catch (Exception e) {
            log.error("邮件配置测试失败，配置ID：{}，错误信息：{}", configId, e.getMessage(), e);
            throw new RuntimeException("邮件发送失败：" + e.getMessage());
        }
    }
    
    @Override
    public boolean updateStatus(Long id, Boolean status) {
        return this.lambdaUpdate()
                .eq(MailSenderConfig::getId, id)
                .set(MailSenderConfig::getStatus, status)
                .update();
    }
    
    /**
     * 根据配置创建邮件发送器
     */
    private JavaMailSender createMailSender(MailSenderConfig config) {
        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
        
        mailSender.setHost(config.getSmtpHost());
        mailSender.setPort(config.getSmtpPort());
        mailSender.setUsername(config.getSenderEmail());
        mailSender.setPassword(config.getSenderPassword());
        
        Properties props = mailSender.getJavaMailProperties();
        props.put("mail.transport.protocol", "smtp");
        props.put("mail.smtp.auth", config.getAuthEnable());
        props.put("mail.smtp.starttls.enable", config.getTlsEnable());
        props.put("mail.smtp.ssl.enable", config.getSslEnable());
        props.put("mail.debug", config.getDebugEnable());
        props.put("mail.smtp.connectiontimeout", config.getConnectionTimeout());
        props.put("mail.smtp.timeout", config.getReadTimeout());
        
        return mailSender;
    }
}